package com.event.management.frontend.service.impl;

import com.event.management.frontend.domain.Users;
import com.event.management.frontend.dto.LoginParam;
import com.event.management.frontend.dto.FrontLoginResponseDTO;
import com.event.management.frontend.dto.FrontUserInfoDTO;
import com.event.management.frontend.dto.RegisterParam;
import com.event.management.frontend.dto.UpdatePasswordParam;
import com.event.management.frontend.dto.UpdateUserParam;
import com.event.management.frontend.dto.UserDetailDTO;
import com.event.management.frontend.mapper.UsersMapper;
import com.event.management.frontend.service.FrontUsersService;
import com.event.management.frontend.service.OrderService;
import com.event.management.frontend.service.UserTicketService;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.text.SimpleDateFormat;

/**
 * 前台用户服务实现类
 */
@Slf4j
@Service
public class FrontUsersServiceImpl implements FrontUsersService {

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private OrderService orderService;
    
    @Autowired
    private UserTicketService userTicketService;

    /**
     * 前台用户登录
     * @param loginParam 登录参数
     * @return 登录结果
     */
    @Override
    public FrontLoginResponseDTO frontLogin(LoginParam loginParam) {
        // 查询用户
        Users user = usersMapper.selectByUsername(loginParam.getUsername());
        
        log.info("前台用户登录: {}, 查询结果: {}", loginParam.getUsername(), user != null ? "存在" : "不存在");
        
        // 验证用户是否存在
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }

        
        // 验证密码是否正确
        String encryptedPassword = DigestUtils.md5DigestAsHex(loginParam.getPassword().getBytes());
        String savedPassword = user.getPassword();
        
        log.info("密码验证 - 输入密码: {}, 数据库密码: {}", encryptedPassword, savedPassword);

        if (!savedPassword.equals(encryptedPassword)) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 生成Token并登录
        StpUtil.login(user.getId());
        log.info("前台用户 {} 登录成功", user.getUsername());
        
        // 在Session中保存用户角色
        StpUtil.getSession().set("role", user.getRole());
        
        // 获取完整的Token信息
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        String tokenValue = tokenInfo.getTokenValue();
        log.info("前台用户 {} 生成token: {}", user.getUsername(), tokenValue);
        
        // 更新用户最后登录时间
        Users updateUser = new Users();
        updateUser.setId(user.getId());
        updateUser.setUpdatedAt(new Date());
        usersMapper.updateById(updateUser);
        
        // 构建返回结果
        FrontUserInfoDTO userInfoDTO = new FrontUserInfoDTO(
                user.getId(),
                user.getUsername(),
                user.getRole(),
                user.getAvatar(), // 头像URL
                user.getEmail(), // 邮箱
                user.getPhone(), // 手机号
                user.getCreatedAt(),
                new Date() // 最后登录时间
        );
        
        return new FrontLoginResponseDTO(tokenValue, userInfoDTO);
    }

    /**
     * 获取当前登录前台用户信息
     * @return 用户信息
     */
    @Override
    public FrontUserInfoDTO getCurrentFrontUserInfo() {
        // 获取当前登录用户ID
        Object loginId = StpUtil.getLoginId();
        Integer userId = Integer.parseInt(loginId.toString());
        
        log.info("获取当前登录前台用户ID: {}", userId);
        
        // 查询用户信息
        Users user = usersMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        log.info("获取到前台用户: {}, 角色: {}", user.getUsername(), user.getRole());
        
        // 返回用户信息
        return new FrontUserInfoDTO(
                user.getId(),
                user.getUsername(),
                user.getRole(),
                user.getAvatar(), // 头像URL
                user.getEmail(), // 邮箱
                user.getPhone(), // 手机号
                user.getCreatedAt(),
                user.getUpdatedAt() // 最后登录时间
        );
    }

    /**
     * 根据用户名查询用户ID
     * @param username 用户名
     * @return 用户ID
     */
    @Override
    public Integer getUserIdByUsername(String username) {
        Users user = usersMapper.selectByUsername(username);
        return user != null ? user.getId() : null;
    }
    
    /**
     * 用户注册
     * @param registerParam 注册参数
     * @return 是否注册成功
     */
    @Override
    public boolean register(RegisterParam registerParam) {
        // 检查用户名是否已存在
        Users existUser = usersMapper.selectByUsername(registerParam.getUsername());
        if (existUser != null) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 处理兴趣爱好默认值
        if (!StringUtils.hasText(registerParam.getInterests())) {
            registerParam.setInterests(generateDefaultInterests());
        }
        
        // 构建用户对象
        Users user = new Users();
        BeanUtils.copyProperties(registerParam, user);
        
        // 处理生日字段 - 转换字符串为Date
        if (StringUtils.hasText(registerParam.getBirthday())) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                user.setBirthday(sdf.parse(registerParam.getBirthday()));
            } catch (Exception e) {
                log.error("日期格式转换错误: {}", e.getMessage());
            }
        }
        
        // 密码加密
        String encryptedPassword = DigestUtils.md5DigestAsHex(registerParam.getPassword().getBytes());
        user.setPassword(encryptedPassword);
        
        // 设置默认用户角色
        user.setRole("user");
        
        // 设置创建和更新时间
        Date now = new Date();
        user.setCreatedAt(now);
        user.setUpdatedAt(now);
        
        // 保存用户
        int result = usersMapper.insert(user);
        return result > 0;
    }
    
    /**
     * 更新用户资料
     * @param updateUserParam 用户资料更新参数
     * @return 是否更新成功
     */
    @Override
    public boolean updateUserInfo(UpdateUserParam updateUserParam) {
        // 获取当前登录用户ID
        Object loginId = StpUtil.getLoginId();
        Integer userId = Integer.parseInt(loginId.toString());
        
        // 查询用户信息
        Users user = usersMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 处理兴趣爱好默认值
        if (updateUserParam.getInterests() != null && updateUserParam.getInterests().trim().isEmpty()) {
            updateUserParam.setInterests(generateDefaultInterests());
        }
        
        // 更新用户信息
        Users updateUser = new Users();
        updateUser.setId(userId);
        BeanUtils.copyProperties(updateUserParam, updateUser);
        
        // 处理生日字段 - 转换字符串为Date
        if (StringUtils.hasText(updateUserParam.getBirthday())) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                updateUser.setBirthday(sdf.parse(updateUserParam.getBirthday()));
            } catch (Exception e) {
                log.error("日期格式转换错误: {}", e.getMessage());
            }
        }
        
        updateUser.setUpdatedAt(new Date());
        
        // 保存更新
        int result = usersMapper.updateUserInfo(updateUser);
        return result > 0;
    }
    
    /**
     * 修改密码
     * @param updatePasswordParam 密码修改参数
     * @return 是否修改成功
     */
    @Override
    public boolean updatePassword(UpdatePasswordParam updatePasswordParam) {
        // 获取当前登录用户ID
        Object loginId = StpUtil.getLoginId();
        Integer userId = Integer.parseInt(loginId.toString());
        
        // 查询用户信息
        Users user = usersMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证旧密码
        String oldEncryptedPassword = DigestUtils.md5DigestAsHex(updatePasswordParam.getOldPassword().getBytes());
        if (!user.getPassword().equals(oldEncryptedPassword)) {
            throw new RuntimeException("旧密码不正确");
        }
        
        // 更新密码
        Users updateUser = new Users();
        updateUser.setId(userId);
        updateUser.setPassword(DigestUtils.md5DigestAsHex(updatePasswordParam.getNewPassword().getBytes()));
        updateUser.setUpdatedAt(new Date());
        
        // 保存更新
        int result = usersMapper.updateUserInfo(updateUser);
        return result > 0;
    }
    
    /**
     * 生成默认的兴趣爱好
     * @return 随机生成的兴趣爱好
     */
    private String generateDefaultInterests() {
        // 默认兴趣列表
        List<String> defaultInterests = Arrays.asList("音乐", "讲座", "运动");
        
        // 随机打乱
        List<String> shuffled = Arrays.asList(defaultInterests.toArray(new String[0]));
        Collections.shuffle(shuffled);
        
        // 随机选择1-3个兴趣
        int count = new Random().nextInt(3) + 1;
        count = Math.min(count, shuffled.size());
        
        // 构建结果
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < count; i++) {
            if (i > 0) {
                result.append("、");
            }
            result.append(shuffled.get(i));
        }
        
        return result.toString();
    }

    /**
     * 获取当前用户详细信息
     * @return 用户详细信息
     */
    @Override
    public UserDetailDTO getCurrentUserDetail() {
        // 获取当前登录用户ID
        Object loginId = StpUtil.getLoginId();
        Integer userId = Integer.parseInt(loginId.toString());
        
        log.info("获取当前用户详细信息, 用户ID: {}", userId);
        
        // 查询用户基本信息
        Users user = usersMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 查询用户订单总数
        long ordersCount = orderService.countMyOrders(userId.longValue());
        
        // 查询用户电子票总数
        long ticketsCount = userTicketService.countUserTickets(userId.longValue());
        
        log.info("用户[{}]订单数: {}, 电子票数: {}", userId, ordersCount, ticketsCount);
        
        // 构建并返回用户详情
        UserDetailDTO userDetailDTO = new UserDetailDTO();
        BeanUtils.copyProperties(user, userDetailDTO);
        userDetailDTO.setOrdersCount(ordersCount);
        userDetailDTO.setTicketsCount(ticketsCount);
        
        return userDetailDTO;
    }
} 